package com.tsmti.tags.form;

import com.tsmti.basicdata.entity.*;
import com.tsmti.business.entity.PimsSysPathology;
import com.tsmti.core.common.constant.RedisConstants;
import com.tsmti.core.util.RedisUtils;
import com.tsmti.core.util.StringUtils;
import com.tsmti.system.entity.DataDictionary;
import com.tsmti.system.entity.User;
import com.tsmti.tags.form.support.CustomBindStatus;
import com.tsmti.util.DictionaryUtils;
import org.springframework.beans.PropertyAccessor;
import org.springframework.web.servlet.support.BindStatus;

import javax.servlet.jsp.JspException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @Package：com.tsmti.tags.form
 * @Class：SelectTag
 * @Description： select标签
 * @Author：
 * @Date：Created in 2018/3/14 17:15
 * @Company:
 * @Version：
 * @Modified By:
 */
@SuppressWarnings("serial")
public class SelectTag extends org.springframework.web.servlet.tags.form.SelectTag {
    private static final Object EMPTY = new Object();
    private BindStatus bindStatus = null;
    /**
     * 是否嵌套使用Form自定的模型，模式为真,nested为false,需要设置对应字段为空字符串否则报错；
     */
    private Boolean nested = true;
    /**
     * 绑定数据字典类型，数据字典优先
     */
    private String dict = "";
    /**
     * 绑定redis数据
     */
    private String redis = "";
    /**
     * 绑定org数据
     */
    private String org = "";
    /**
     * 1,bean
     * 2,通过参数获取。3.获取getAttribute中的值
     */
    private String valueWay = "";
    /**
     * 默认值
     */
    private String defaultValue = "";

    /**
     * 是否包含空选项
     */
    private Boolean emptyItem = true;

    @Override
    protected BindStatus getBindStatus() throws JspException {
        if (this.bindStatus == null) {
            // HTML escaping in tags is performed by the ValueFormatter class.
            String nestedPath = "";
            if (nested) {
                nestedPath = getNestedPath();
            }
            String pathToUse = (nestedPath != null ? nestedPath + getPath() : getPath());
            if (pathToUse.endsWith(PropertyAccessor.NESTED_PROPERTY_SEPARATOR)) {
                pathToUse = pathToUse.substring(0, pathToUse.length() - 1);
            }
            this.bindStatus = CustomBindStatus.create(pageContext, pathToUse, getRequestContext(), false, nested,
                    valueWay, defaultValue);
        }
        return this.bindStatus;
    }

    public Boolean getNested() {
        return nested;
    }

    public void setNested(Boolean nested) {
        this.nested = nested;
    }

    public String getDict() {
        return dict;
    }

    public void setDict(String dict) {
        this.dict = dict;
    }

    private List getTrueList(List list,String orgId){
        if(StringUtils.isNotEmpty(orgId) && list != null && list.size() > 0){
            Iterator it = list.iterator();
            while(it.hasNext()){
                Object o = it.next();
                Class<?> clazz = o.getClass();
                for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
                    Field[] fields = clazz.getDeclaredFields();
                    for( Field field : fields){
                        field.setAccessible(true);
                        try {
                            String name = field.getName();
                            if("ORGID".equals(name.toUpperCase())){
                                name = name.substring(0, 1).toUpperCase() + name.substring(1);
                                try {
                                    Method m = o.getClass().getMethod("get" + name);
                                    try {
                                        String value = m.invoke(o) == null?"":m.invoke(o).toString();
                                        if (!orgId.equals(value)) {
                                            it.remove();
                                        }
                                    } catch (InvocationTargetException e) {
                                        e.printStackTrace();
                                    }
                                } catch (NoSuchMethodException e) {
                                    e.printStackTrace();
                                }
                            }
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        return list;
    }

    @Override
    protected Object getItems() {
        if (!StringUtils.isEmpty(dict)) {
            List<DataDictionary> dictionaryList = DictionaryUtils.getDictList(dict);
            if (this.emptyItem) {
                DataDictionary dictionary = new DataDictionary();
                dictionary.setName("请选择");
                dictionary.setCode("");
                dictionaryList.add(0, dictionary);
            }
            return dictionaryList;
        }
        if (!StringUtils.isEmpty(redis)) {
            try {
                List list = RedisUtils.getRedisToList(redis);
                list = getTrueList(list,org);
                Map map = new HashMap(16);
                map.put("code","");
                map.put("name","请选择");
                switch (redis) {
                    case RedisConstants.WARD_CACHE:
                        List<WardInformation> wardInformationList = list;
                        if (this.emptyItem) {
                            list.add(0, RedisUtils.getByReflect(new WardInformation().getClass(), map));
                        }
                        return wardInformationList;
                    case RedisConstants.DEPT_CACHE:
                        List<DeptInfomation> deptInfomationList = list;
                        if (this.emptyItem) {
                            list.add(0, RedisUtils.getByReflect(new DeptInfomation().getClass(), map));
                        }
                        return deptInfomationList;
                    case RedisConstants.DOCTORANDNURSE_CACHE:
                        List<DoctorInformation> doctorInformationList = list;
                        if (this.emptyItem) {
                            list.add(0, RedisUtils.getByReflect(new DoctorInformation().getClass(), map));
                        }
                        return doctorInformationList;
                    case RedisConstants.DOCTOR_CACHE:
                        List<DoctorInformation> doctorList = list;
                        if (this.emptyItem) {
                            list.add(0, RedisUtils.getByReflect(new DoctorInformation().getClass(), map));
                        }
                        return doctorList;
                    case RedisConstants.PHY_USER_CACHE:
                        List<User> userList = list;
                        if(userList != null && userList.size() > 0){
                            for(User user:userList){
                                user.setCode(user.getId()+"");
                                user.setName(user.getRealName());
                            }
                        }

                        if (this.emptyItem) {
                            map = new HashMap(16);
                            map.put("userName","");
                            map.put("name","请选择");
                            list.add(0, RedisUtils.getByReflect(new User().getClass(), map));
                        }
                        return userList;
                    case RedisConstants.SYS_PATHOLOGY:
                        List<PimsSysPathology> pimsSysPathologyList = list;
                        for(PimsSysPathology pimsSysPathology:pimsSysPathologyList){
                            pimsSysPathology.setCode(pimsSysPathology.getId()+"");
                            pimsSysPathology.setName(pimsSysPathology.getPatNamech());
                        }
                        if (this.emptyItem) {
                            PimsSysPathology pimsSysPathology = new PimsSysPathology();
                            pimsSysPathology.setPatNamech("请选择");
                            pimsSysPathology.setName("请选择");
                            list.add(0, pimsSysPathology);
                        }
                        return pimsSysPathologyList;
                    default:
                        return null;
                }
            } catch (Exception e) {
                logger.warn("读取系统参数缓存失败!");
                e.printStackTrace();
            }
        }
        return super.getItems();
    }

    @Override
    protected String getItemLabel() {
        if (!StringUtils.isEmpty(dict)) {
            return "name";
        }
        if (!StringUtils.isEmpty(redis)) {
            return "name";
        }
        return super.getItemLabel();
    }

    @Override
    protected String getItemValue() {
        if (!StringUtils.isEmpty(dict)) {
            return "code";
        }
        if (!StringUtils.isEmpty(redis)) {
            return "code";
        }
        return super.getItemValue();
    }

    @Override
    public void doFinally() {
        super.doFinally();
        this.bindStatus = null;
    }

    public String getValueWay() {
        return valueWay;
    }

    public void setValueWay(String valueWay) {
        this.valueWay = valueWay;
    }

    public String getDefaultValue() {
        return defaultValue;
    }

    public void setDefaultValue(String defaultValue) {
        this.defaultValue = defaultValue;
    }

    public void setBindStatus(BindStatus bindStatus) {
        this.bindStatus = bindStatus;
    }

    public Boolean getEmptyItem() {
        return emptyItem;
    }

    public void setEmptyItem(Boolean emptyItem) {
        this.emptyItem = emptyItem;
    }

    public String getRedis() {
        return redis;
    }

    public void setRedis(String redis) {
        this.redis = redis;
    }

    public String getOrg() {
        return org;
    }

    public void setOrg(String org) {
        this.org = org;
    }
}
